package com.company.project.search.engine;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.company.project.search.entity.Search;
import com.company.project.search.util.OkHttpUtil;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 北大法宝
 * https://www.pkulaw.com/
 */

public final class E2 extends AbstractE implements Callback {

    private static final String host = "https://www.pkulaw.com";

    //    private static final String url = "https://www.pkulaw.com/law/chl";
    private static final String url2 = "https://www.pkulaw.com/law/search/RecordSearch";

    private static final Headers headers = new Headers.Builder()
            .add("Origin", "https://www.pkulaw.com")
            .add("Referer", "https://www.pkulaw.com/")
            .add("Accept", "*/*")
            .add("Accept-Language", "zh-CN,zh;q=0.9")
            .add("Connection", "keep-alive")
            .add("sec-ch-ua", "\"Google Chrome\";v=\"95\", \"Chromium\";v=\"95\", \";Not A Brand\";v=\"99\"")
            .add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
            .add("Cache-Control", "no-cache")
            .add("sec-ch-ua-platform:", "Windows")
            .add("X-Requested-With", "XMLHttpRequest")
            .add("Sec-Fetch-Site", "same-origin")
            .add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36")
            .build();

    private void parse(Document html, Result result) {

        Result.Header header = new Result.Header();

        Elements title = html.getElementsByClass("pagination pagination-sm");
        if (title != null && !title.isEmpty()) {
            Element totalUL = title.get(0);
            if (totalUL != null) {
                Elements lis = totalUL.getElementsByClass("disabled");
                if (lis != null && !lis.isEmpty()) {
                    String pages = lis.get(0).text();
                    Pattern pattern = Pattern.compile("/[0-9]+");
                    Matcher matcher = pattern.matcher(pages);
                    if (matcher.find()) {
                        String g = matcher.group();
                        if (g != null) {
                            g = g.replaceAll("/", "");
                            try {
                                header.maxPage = Integer.parseInt(g);
                            } catch (NumberFormatException ignored) {

                            }
                        }
                    }
                }
            }
        }

        /*
         *
         * {"FieldName":null,"Value":null,"RuleType":4,"ManyValueSplit":"\u0000","WordMatchType":0,"WordRate":0,"CombinationType":2,"ChildNodes":[{"FieldName":"KeywordSearchTree","Value":null,"RuleType":4,"ManyValueSplit":"\u0000","WordMatchType":0,"WordRate":0,"CombinationType":1,"ChildNodes":[{"FieldName":"Title","Value":"民","RuleType":4,"ManyValueSplit":"\u0000","WordMatchType":2,"WordRate":0,"CombinationType":2,"ChildNodes":[],"Analyzer":"ik_max_word","Boost":null,"Minimum_should_match":"90%"}],"Analyzer":null,"Boost":null,"Minimum_should_match":null}],"Analyzer":null,"Boost":null,"Minimum_should_match":null}
         *
         * */

        header.maxPage = 0;
        header.engine = Engine.ID_E2;
        header.engineName = "北大法宝";
        result.headers = new HashSet<>();
        result.headers.add(header);


        Elements elements = html.getElementsByClass("block");
        List<Search> list = new ArrayList<>();
        for (Element e : elements) {
            Search tto = Search.newInstance(Engine.ID_E2);

            Elements list_title = e.getElementsByClass("list-title");
            if (list_title.size() == 1) {
                Elements title_a = list_title.get(0).getElementsByTag("a");
                String name = title_a.get(0).text();
                String url = title_a.attr("href");
                if (name == null || "".equals(name.trim())) continue;
                if (url == null || "".equals(url.trim())) continue;
                tto.setUrl(host.concat(url));
                tto.setName(name);
                tto.setCategory("2-1");
                tto.setSource("北大法宝");
            } else {
                continue;
            }

            Elements related_info = e.getElementsByClass("related-info");
            if (related_info.size() == 1) {
                String date = related_info.get(0).text();
                tto.setSource(date);
            } else {
                continue;
            }
            list.add(tto);
        }
        result.list = list;
        if (callback != null) callback.callback(result);
    }

    @Override
    public void onFailure(@NotNull Call call, @NotNull IOException e) {
        System.out.println("E4 onFailure");
    }

    @Override
    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
        if (response.isSuccessful()) {
            ResponseBody responseBody = response.body();
            if (responseBody != null) {
                String json = responseBody.string();
                Document html = Jsoup.parse(json);
                Param p = (Param) call.request().tag();
                if (p != null) System.out.println("E2响应成功:" + (System.currentTimeMillis() - p.duration) + "ms");
                Result result = new Result(p);
                parse(html, result);
            }
        }
    }

    @Override
    public void search(Param p) {
        p.engine = Engine.ID_E2;

        Result result = new Result(p);
        Result.Header header = new Result.Header();
        header.engineName = "";
        header.engine = Engine.ID_E2;
        header.maxPage = 1;
        header.totalCount = 20;
        result.headers = new HashSet<>();
        result.headers.add(header);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("FieldName", null);
        jsonObject.put("Value", null);
        jsonObject.put("RuleType", 4);
        jsonObject.put("ManyValueSplit", "\u0000");
        jsonObject.put("WordMatchType", 0);
        jsonObject.put("WordRate", 0);
        jsonObject.put("CombinationType", 2);
        jsonObject.put("Analyzer", null);
        jsonObject.put("Boost", null);
        jsonObject.put("Minimum_should_match", null);
        JSONArray childNodes = new JSONArray();
        JSONObject node = new JSONObject();
        node.put("FieldName", "KeywordSearchTree");
        node.put("Value", null);
        node.put("RuleType", 4);
        node.put("ManyValueSplit", "\u0000");
        node.put("WordMatchType", 0);
        node.put("WordRate", 0);
        node.put("CombinationType", 1);
        JSONArray jsonArray = new JSONArray();
        JSONObject nodeNode = new JSONObject();
        nodeNode.put("FieldName", "Title");
        nodeNode.put("Value", p.keyword);
        nodeNode.put("RuleType", 4);
        nodeNode.put("ManyValueSplit", "\u0000");
        nodeNode.put("WordMatchType", 2);
        nodeNode.put("WordRate", 0);
        nodeNode.put("CombinationType", 2);
        nodeNode.put("ChildNodes", new JSONArray());
        nodeNode.put("Analyzer", "ik_max_word");
        nodeNode.put("Boost", null);
        nodeNode.put("Minimum_should_match", "90%");
        jsonArray.add(nodeNode);
        node.put("ChildNodes", jsonArray);
        childNodes.add(node);
        jsonObject.put("ChildNodes", childNodes);
        String json = jsonObject.toJSONString();

        RequestBody body = new FormBody.Builder()
                .add("Menu", "law")
                .add("Keywords", p.keyword)
                .add("PreKeywords", p.keyword)
                .add("SearchKeywordType", "Title")
                .add("MatchType", "Fuzzy")
                .add("RangeType", "Piece")
                .add("IsSentenceSearch", "Piece")
                .add("Library", "chl")
                .add("ClassFlag", "chl")
                .add("QueryOnClick", "False")
                .add("AfterSearch", "True")
                .add("GroupLibraries", "")
                .add("QuerySearchCondition", "Title+Exact+Piece+0")
                .add("RequestFrom", "btnSearch")
                .add("SearchInResult", "")
                .add("PreviousLib", "chl")
                .add("IsSynonymSearch", "false")
                .add("RecordShowType", "List")
                .add("ClassCodeKey", ",,,,,,")
                .add("IsSearchErrorKeyword", "")
                .add("IsAdv", "False")
                .add("GroupByIndex", "0")
                .add("RecordShowType", "List")
                .add("ShowType", "Default")
                .add("OrderByIndex", "4")
                .add("Pager.PageIndex", String.valueOf(p.curPage - 1))
                .add("Pager.PageSize", "10")
                .add("OldPageIndex", "49")
                .add("LastLibForChangeColumn", "chl")
                .add("X-Requested-With", "XMLHttpRequest")
                .add("QueryBase64Request", Base64.getEncoder().encodeToString(json.getBytes()))
                .build();

        Request request = new Request.Builder()
                .url(url2)
                .headers(headers)
                .tag(p)
                .post(body)
                .build();

        OkHttpUtil.getInstance().enqueue(request, this);
    }

    @Override
    public JSONArray provideCategory() {
        JSONArray list = new JSONArray();
        list.add(new Category("2-1", "北大法宝"));
        list.add(new Category("2-0", "北大法宝其他类别"));
        return list;
    }

    private static final class Holder {
        private static final AbstractE ins = new E2();
    }

    private E2() {

    }

    public static AbstractE getInstance() {
        return Holder.ins;
    }
}
